Refactor: Team settings page#292
Conversation
Restructure the members page around a richer client table and dialog-based invite flow, while preserving the corrected removal and inviter behaviors with focused coverage. Made-with: Cursor
- Introduced `isPendingTeamMember` utility to determine pending invites based on provider recognition. - Updated member table row logic to utilize the new utility for better clarity on member status. - Refined the Add Member dialog and form for improved user experience, including UI adjustments and label updates. - Enhanced members page content to display pending member counts alongside total members. These changes aim to streamline the member management process and improve the overall dashboard experience.
- Simplified the Add Member dialog by consolidating class names for better styling. - Removed unnecessary Card components from MemberCard for a cleaner layout. - Introduced a new RemoveMemberDialog component to enhance member removal interactions. - Adjusted member table row and cell components for improved responsiveness and clarity. These changes aim to streamline the user experience in managing team members on the dashboard.
- Updated the ProvidersCell component to improve responsiveness by displaying a single provider badge on smaller screens and all providers on larger screens. - Adjusted column widths in the MemberTable for better alignment and consistency across different screen sizes. These changes enhance the user experience by ensuring that member information is displayed clearly and effectively across various devices.
- Removed unnecessary `not-italic` class from various buttons and input fields in the Add Member dialog and form for a cleaner look. - Adjusted the `NameCell` and `ProvidersCell` components to enhance readability and responsiveness. - Updated the search input in the MembersPageContent to streamline styling. These changes aim to improve the overall user experience and maintain a consistent design across member management components.
- Introduced a new `Page` component to standardize layout across dashboard pages. - Updated `MembersPage` to wrap content in the `Page` component for improved structure and styling consistency. These changes enhance the overall user experience by providing a unified layout approach for member management components.
- Renamed `AddMemberEmailForm` to `AddMemberForm` for better alignment with its functionality. - Updated type definitions to reflect the new naming convention. - Adjusted the Add Member dialog to utilize the renamed form component. These changes enhance code readability and maintain a consistent naming structure across member management components.
- Added `formatDate` utility to format dates with specified structures, improving date handling across the application. - Updated `MemberTableRow` to utilize the new `formatDate` function for displaying member creation dates. - Introduced `TableEmptyState` component to replace the previous empty state implementation in the member table for better clarity and consistency. These changes enhance the user experience by providing clearer date formatting and improving the overall structure of the member table.
- Moved the `RemoveMemberDialog` component to its own file for better organization and maintainability. - Simplified the `member-table-row` by removing the inline dialog implementation, enhancing readability. - Updated the dialog's structure and styling for a more consistent user experience. These changes aim to streamline the member removal process and improve code organization within the dashboard components.
- Renamed `isSystemAddedMember` to `wasAddedBySystem` and `isPendingTeamMember` to `isPendingInvite` for improved clarity in their functionality. - Updated all relevant tests and components to reflect the new function names, ensuring consistent usage across the application. These changes enhance code readability and maintain a clear understanding of member status within the dashboard components.
- Introduced a new `pluralize` function to handle singular and plural word forms based on count, enhancing text display consistency. - Updated `MembersPageContent` to utilize the `pluralize` function for member count display. - Removed the `isPendingInvite` function from member table utilities and adjusted related components to streamline member status handling. These changes improve code clarity and enhance the user experience by providing accurate member count representations.
…consistency and clarity. - Replaced the previous implementation of the InvoicesEmpty component with the new TableEmptyState component, enhancing the visual structure of empty states. - Updated the member table to streamline the rendering of empty states, ensuring a more uniform approach across the application. These changes improve code maintainability and user experience by providing a consistent empty state presentation.
- Refactored the GeneralPage component to utilize a new layout structure, improving the organization of team-related information. - Added new user messages for team logo removal scenarios to enhance user feedback. - Updated the TeamsRepository interface to allow for null profile picture URLs, improving flexibility in team profile management. - Added .cursor/ to .gitignore to prevent tracking of cursor-related files. These changes improve the user experience and code maintainability across the application.
Made-with: Cursor # Conflicts: # src/features/dashboard/members/add-member-form.tsx # src/features/dashboard/members/member-table.tsx # src/features/dashboard/members/members-page-content.tsx
- Added DangerZone component to the GeneralPage for team deletion functionality. - Introduced TeamAvatar component for improved avatar handling in sidebar menus. - Implemented TeamInfo component to display team creation date and primary email. - Created RemovePhotoDialog for confirming profile picture removal. - Updated models to include createdAt field for teams. - Refactored user-teams-repository to fetch team creation dates from the database. These changes improve user experience and maintainability of the team settings interface.
- Removed the createdAt field from the TeamModel type to simplify the model structure. - Updated the UserTeamsRepository to directly return team data without fetching creation dates from the database. - Adjusted the TeamInfo component to reflect the removal of the createdAt prop, displaying a placeholder instead. These changes enhance code clarity and maintainability by reducing unnecessary complexity in team data management.
- Introduced a utility function `getStorageFilePath` to streamline file path construction for team-related storage. - Updated the `removeTeamProfilePictureAction` and `uploadTeamProfilePictureAction` to utilize the new utility function, enhancing code readability and maintainability. These changes simplify file path management in team actions, contributing to cleaner code.
- Introduced file upload functionality for team profile pictures, including validation for file type and size. - Updated the TeamAvatar component to handle image uploads and removals using TRPC mutations. - Refactored TeamName component to utilize TRPC for updating team names, enhancing state management and user feedback. - Created a new file schema for consistent file handling across components. These changes improve the user experience and maintainability of the team settings interface.
- Consolidated team member schemas, including AddTeamMemberSchema and RemoveTeamMemberSchema, for better organization and clarity. - Updated team actions to utilize TRPC for adding and removing team members, enhancing state management and user feedback. - Refactored the AddMemberForm and MemberTableRow components to integrate the new TRPC mutations, improving the user experience when managing team members. These changes streamline team member management and enhance the maintainability of the codebase.
- Introduced TRPC queries for fetching team members in the MembersPage and MemberCard components, enhancing data handling and user experience. - Replaced the previous loading and error handling mechanisms with a more streamlined approach using the new TableLoadingState and ErrorIndicator components. - Updated the AddMemberForm and MemberTableRow components to utilize query invalidation for better state management after mutations. - Removed the deprecated getTeamMembers function to clean up the codebase. These changes improve the maintainability and responsiveness of the team members interface.
…r handling - Introduced dynamic font sizing for the team name input, adjusting based on available width to ensure optimal display. - Added validation error handling using TRPC, displaying user-friendly messages for form errors and field-specific issues. - Refactored the component to utilize a text measurement span for accurate font size adjustments during editing. These changes improve the user experience and maintainability of the TeamName component in the dashboard settings.
- Updated the GeneralPage component to streamline the layout by integrating styles directly into the Page component. - Removed the DangerZone component from the GeneralPage, simplifying the interface and focusing on essential team information. - Added 'use client' directive to the loader component for improved client-side rendering. These changes enhance the clarity and maintainability of the dashboard settings interface.
- Removed the className prop from the MemberCard component, streamlining its interface. - Updated the Card component to eliminate unnecessary className usage, improving layout consistency. - Adjusted CardContent to include padding directly, enhancing visual presentation. These changes improve the maintainability and clarity of the MemberCard component in the dashboard.
- Changed the input field height from 40px to 32px for better alignment with design specifications. - Updated the line height to reflect the new constant, enhancing the overall appearance and readability of the team name input. These changes contribute to a more polished user interface in the dashboard settings.
# Conflicts: # src/core/server/actions/team-actions.ts
- Deleted the team-actions.ts file to streamline action handling. - Integrated team creation functionality directly into the TRPC router for better type safety and consistency. - Updated CreateTeamDialog component to utilize TRPC for team creation, enhancing the user experience with improved error handling and state management. These changes simplify the codebase and improve the overall architecture of team management features.
There was a problem hiding this comment.
can you check if there is a better, more native way, to do file uploads inside trpc than base64 ?
There was a problem hiding this comment.
good callout. i initially leaned into base64 here because our existing support file upload flow already uses the same pattern, so I was keeping avatar upload consistent with that.
i did look into the more native tRPC v11 path: it supports FormData / non-JSON inputs directly, but because we currently use the batched streaming link for tRPC, uploads need to be routed through a separate non-batched httpLink transport. So it’s doable, but it adds a bit of client/server plumbing versus the simpler base64 shape.
| const TEAM_NAME_MAX_FONT_SIZE_PX = 32 | ||
| const TEAM_NAME_MIN_FONT_SIZE_PX = 18 | ||
| const TEAM_NAME_LINE_HEIGHT_PX = 32 |
There was a problem hiding this comment.
this is the design spec from Vojtech, the team name should auto-shrink to fit the available width rather than truncate or wrap. see Figma.
the three constants are the inputs to the measure-and-shrink loop in the effect below: starting size, floor, and a fixed line-height to keep the row from jumping as the font size changes.
| const TrpcErrorWithZodDataSchema = z.object({ | ||
| data: z | ||
| .object({ | ||
| zodError: z | ||
| .object({ | ||
| formErrors: z.array(z.string()), | ||
| fieldErrors: z.record(z.string(), z.array(z.string()).optional()), | ||
| }) | ||
| .nullable() | ||
| .optional(), | ||
| }) | ||
| .optional(), | ||
| }) |
There was a problem hiding this comment.
we're parsing the tRPC error envelope to pull out the server-side ZodError payload (formErrors + fieldErrors) so we can surface validation messages as toasts in team-name.tsx and create-team-dialog.tsx.
Using a Zod schema + safeParse because the helper is called from many call sites whose error types don't unify (each procedure's TRPCClientErrorLike is parameterized differently, plus useQuery returns Error | null), and tRPC's typed fieldErrors collapses to {} since flattenError is over unknown, so we'd need a cast either way.
… improved UI consistency. Update loading states for buttons to display descriptive text during actions. Enhance RemovePhotoDialog button loading state for better user feedback.
…r improved structure and functionality. Remove obsolete MemberCard component and enhance MemberTable to accept children for dynamic row rendering. Update MembersPageContent to utilize suspense for data fetching and improve loading states.
…nt for maximum team name length. This improves maintainability and ensures consistent validation messages across the application.
…rTeamsRepository. Update related tests to ensure validation error handling for team creation is consistent. Remove obsolete createTeam method from TeamsRepository to streamline functionality.
…mline navigation after team creation.
…styling flexibility. Update usages in DashboardSidebarMenu and DashboardSidebarMenuTeams to utilize new classNames structure.
- Introduced a new loader component with customizable variants (slash, square, dots) and sizes (sm, md, lg, xl). - Created a dedicated CSS module for styling the loader, including keyframe animations for each variant. - Refactored the loader implementation to use class names instead of styled-components for improved maintainability and performance.

Ticket